package my;

import android.bluetooth.BluetoothGatt;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.View;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleMtuChangedCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.utils.BleLog;
import com.clj.fastble.utils.HexUtil;
import com.ffapp.f9164.td.basis.BasisActivity;
import com.ffapp.f9164.td.basis.Constants;
import com.ffapp.f9164.td.common.ObserverManager;
import com.ffapp.f9164.td.eventbus.PopHandleMessage;
import com.ffapp.f9164.td.login.LoginActivity;
import com.ffapp.f9164.td.login.LoginView;
import com.ffapp.f9164.td.util.CountDown;
import com.ffapp.f9164.td.util.MessageUtil;
import com.flyco.dialog.listener.OnBtnClickL;
import com.google.common.primitives.Bytes;
import com.mylhyl.circledialog.CircleDialog;

import org.greenrobot.eventbus.EventBus;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BleUtils {

    public static Handler submitHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 76:  //检查是否传输完毕
                    if (!isFinish) {
                        isFinish = true;
                        bleUtilCallBack.onError("查询超时，请重试！");
                        stopNotify();
                    }
                    break;
            }

        }
    };

    private static BleDevice bleDevice = null;
    private static StringBuffer atShowResult;
    private static StringBuffer atSearchResult;
    private static List<Byte> atSearchResultByteList;

    public static boolean isFinish = false;
    public static BleUtilCallBack bleUtilCallBack;
    private static CountDown mCountDownTimer;
    private static final long MAX_TIME = 15 * 1000;
    private static final long RE_MAX_TIME = 25 * 1000;
    private static Context mContext;

    private static String passWord ;
    private static BleUtilLoginCallBack bleUtilLoginCallBack ;
    public static boolean isCancel = false;

    public BleUtils(){

    }

    public static BleDevice getBleDevice() {
        if (bleDevice == null) {
            return null;
        }
        return bleDevice;
    }

    public static void stopConnectDevice() {
        isCancel = true;
        if (bleGattCallback != null) {
            if (bleDevice != null) {
                BleManager.getInstance().removeConnectGattCallback(bleDevice);
                ObserverManager.getInstance().notifyObserver(bleDevice);
            }
        }
    }

    public static BleGattCallback bleGattCallback = new BleGattCallback() {
        @Override
        public void onStartConnect() {

        }

        @Override
        public void onConnectFail(BleDevice bleDevice, BleException exception) {
            DialogUtils.DialogTwo(mContext, "", "连接失败,是否重新连接？", "确定", "取消", new OnBtnClickL() {
                @Override
                public void onBtnClick() {
                    connect(getBleDevice(), mContext, passWord, bleUtilLoginCallBack);
                }
            }, new OnBtnClickL() {
                @Override
                public void onBtnClick() {
                    bleUtilLoginCallBack.isLogin(false,"您已取消");
                }
            });
        }

        @Override
        public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
            LoginActivity.isConnect = true;
            checkPwd(bleDevice,passWord,bleUtilLoginCallBack);
        }

        @Override
        public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
            LoginActivity.isLogin = isActiveDisConnected;
            ObserverManager.getInstance().notifyObserver(bleDevice);
            EventBus.getDefault().post(new PopHandleMessage("disconnect"));
        }
    };

    public static void reConnect(final BasisActivity mContext, final BleUtilLoginCallBack bleUtilLoginCallBack){
        new CircleDialog.Builder()
                .setTitle("提示")
                .setText("蓝牙连接断开，请重新连接！")
                .setPositive("确定", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mContext.showLoading();
                        connect(getBleDevice(),mContext,passWord,bleUtilLoginCallBack);
                    }
                })
                .show(mContext.getSupportFragmentManager());
    }

    public static void connect(BleDevice device, Context context,String pwd,BleUtilLoginCallBack loginCallBack) {
        if(mCountDownTimer == null){
            mCountDownTimer = new CountDown();
            mCountDownTimer.setMillisInFuture(MAX_TIME);
            mCountDownTimer.setCountdownInterval(1000);
            mCountDownTimer.setCountDownListener(new CountDown.CountDownListener() {
                @Override
                public void onStart() {
                }

                @Override
                public void onFinish() {
                    BleLog.d("BleUtils 等待时间  ====   finish");
                    submitHandler.sendEmptyMessage(Constants.CHECK_FINISH);
                }

                @Override
                public void onTick(long millisUntilFinished) {
                    BleLog.d("BleUtils 等待时间  ====   " + millisUntilFinished);
                }
            });
        }
        mContext = context;
        bleDevice = device;
        stopConnectDevice();
        isCancel = false;
        passWord = pwd;
        bleUtilLoginCallBack = loginCallBack;
        BleManager.getInstance().connect(device, bleGattCallback);
    }



    public static void checkPwd(BleDevice device, String pwd, final BleUtilLoginCallBack bleUtilLoginCallBack) {
        final String pwdHex = HexUtil.strToHex("AT+AUTHLOGON=" + pwd + "]");
        if (bleDevice == null) {
            return;
        }
        atSearchResult = new StringBuffer();
        BleManager.getInstance().notify(
                bleDevice,
                Constants.DATA_TRANSMISSION,
                Constants.SPP_CMD_RESP,
                new BleNotifyCallback() {
                    @Override
                    public void onNotifySuccess() {
                        BleManager.getInstance().write(
                                bleDevice,
                                Constants.DATA_TRANSMISSION,
                                Constants.SPP_CMD_WRITE,
                                HexUtil.hexStringToBytes(pwdHex),
                                new BleWriteCallback() {
                                    @Override
                                    public void onWriteSuccess(int current, int total, byte[] justWrite) {

                                    }

                                    @Override
                                    public void onWriteFailure(BleException exception) {

                                    }
                                });
                    }

                    @Override
                    public void onNotifyFailure(BleException exception) {

                    }

                    @Override
                    public void onCharacteristicChanged(byte[] data) {
                        for (Byte a : data) {
                            atSearchResult.append(String.format("%02X", a));
                        }
                        String sMes = HexUtil.hexStringToString(atSearchResult.toString());
                        if (sMes.contains("OK")){
                            bleUtilLoginCallBack.isLogin(true,"登录成功");
                            BleManager.getInstance().stopNotify(bleDevice, Constants.DATA_TRANSMISSION, Constants.SPP_CMD_RESP);
                        }
                    }

                    @Override
                    public void onError() {
                        //关闭监听
                        bleUtilLoginCallBack.isLogin(false,"密码错误");
                        BleManager.getInstance().stopNotify(bleDevice, Constants.DATA_TRANSMISSION, Constants.SPP_CMD_RESP);
                    }
                }
        );
    }

    public static void write(String hexAction) {
        if (bleDevice == null) {
            return;
        }
        BleManager.getInstance().write(
                bleDevice,
                Constants.DATA_TRANSMISSION,
                Constants.SPP_DATA_PhoneToModule,
                HexUtil.hexStringToBytes(hexAction),
                new BleWriteCallback() {
                    @Override
                    public void onWriteSuccess(int current, int total, byte[] justWrite) {

                    }

                    @Override
                    public void onWriteFailure(BleException exception) {

                    }
                });

    }


    public static void setMtu(int mtu) {
        if (bleDevice == null) {
            return;
        }
        BleManager.getInstance().setMtu(bleDevice, mtu, new BleMtuChangedCallback() {
            @Override
            public void onSetMTUFailure(BleException exception) {
                // 设置MTU失败
            }

            @Override
            public void onMtuChanged(int mtu) {
                // 设置MTU成功，并获得当前设备传输支持的MTU值
            }
        });
    }

    public static void setMtu(int mtu, BleMtuChangedCallback bleMtuChangedCallback) {
        if (bleDevice == null) {
            return;
        }
        BleManager.getInstance().setMtu(bleDevice, mtu, bleMtuChangedCallback);
    }


    public static void write(String hexAction, BleWriteCallback bleWriteCallback) {
        if (bleDevice == null) {
            return;
        }else {

        }


        BleManager.getInstance().write(
                bleDevice,
                Constants.DATA_TRANSMISSION,
                Constants.SPP_DATA_PhoneToModule,
                HexUtil.hexStringToBytes(hexAction),
                bleWriteCallback);

    }


    public static void write(byte[] action, BleWriteCallback bleWriteCallback) {
        if (bleDevice == null) {
            return;
        }
        BleManager.getInstance().write(
                bleDevice,
                Constants.DATA_TRANSMISSION,
                Constants.SPP_DATA_PhoneToModule,
                action,
                bleWriteCallback);

    }

    public static void write(BleDevice device, String hexAction, BleWriteCallback bleWriteCallback) {
        if (device == null) {
            return;
        }
        BleManager.getInstance().write(
                bleDevice,
                Constants.DATA_TRANSMISSION,
                Constants.SPP_DATA_PhoneToModule,
                HexUtil.hexStringToBytes(hexAction),
                bleWriteCallback);

    }

    public static void write(final String path, final BleUtilCallBack atShowCallBack) {
        if (bleDevice == null) {
            return;
        }
        mCountDownTimer.start();
        isFinish = false;
        BleUtils.bleUtilCallBack = atShowCallBack;
        BleUtils.notify(new BleNotifyCallback() {
            @Override
            public void onNotifySuccess() {
                BleUtils.write(getMessageAgreement("4e", path), new BleWriteCallback() {
                    @Override
                    public void onWriteSuccess(int current, int total, byte[] justWrite) {

                    }

                    @Override
                    public void onWriteFailure(BleException exception) {

                    }
                });
            }

            @Override
            public void onNotifyFailure(BleException exception) {
//                        BleLog.d("下发设置打开通知操作失败");
            }

            @Override
            public void onCharacteristicChanged(byte[] data) {
                String sMes = HexUtil.bytesToAscii(data);
                BleLog.d("报文返回==" + Arrays.toString(data));
                BleLog.d("报文返回==" + HexUtil.bytesToHexString(data));
                for (byte a : data) {
                    BleLog.d("报文返回==" + HexUtil.bytesToHexString(a));
                }
            }

            @Override
            public void onError() {
                //关闭监听
                isFinish = true;
                BleLog.d("BleUtils ==onError== isFinish=== " + isFinish);
                atShowCallBack.onError("查询失败");
                stopNotify();
            }
        });

    }

    public static long MSG_AG_LEN = 200;

    private static byte[] getMessageAgreement(String type, String path) {
        switch (type) {
            case "4e":
                byte[] agreement = MessageUtil.getUpgradeNotice(path);
                return agreement;
            case "52":
                break;
            case "46":
                break;
            case "47":
                break;
        }
        return new byte[0];
    }


    public static void notify(BleNotifyCallback bleNotifyCallback) {
        if (bleDevice == null) {
            return;
        }
        BleManager.getInstance().notify(
                bleDevice,
                Constants.DATA_TRANSMISSION,
                Constants.SPP_DATA_ModuleToPhone,
                bleNotifyCallback
        );

    }


    public static void stopNotify() {
        if (bleDevice == null) {
            return;
        }
        BleManager.getInstance().stopNotify(bleDevice, Constants.DATA_TRANSMISSION, Constants.SPP_DATA_ModuleToPhone);
    }

    public static void stopDownTimer() {
        if (mCountDownTimer == null) {
            return;
        }
        mCountDownTimer.cancel();
    }


    public static void sendAtShow(final BleUtilCallBack atShowCallBack) {
        mCountDownTimer.start();
        isFinish = false;
        atShowResult = new StringBuffer();
        BleUtils.bleUtilCallBack = atShowCallBack;
        BleUtils.notify(new BleNotifyCallback() {
            @Override
            public void onNotifySuccess() {
                String hexString = HexUtil.strToHex("AT+SHOW");
                BleUtils.write(BleUtils.getBleDevice(), hexString, new BleWriteCallback() {
                    @Override
                    public void onWriteSuccess(final int current, final int total, final byte[] justWrite) {
                        if (current == total) {
                            BleLog.d("BleUtils   ====   下发设置发送成功");
                        }
                    }

                    @Override
                    public void onWriteFailure(final BleException exception) {
                        BleLog.d("BleUtils  ==  at+SHOW指令失败");
                        atShowCallBack.onWriteFailure("获取设备数失败");
                    }
                });

            }

            @Override
            public void onNotifyFailure(BleException exception) {
//                        BleLog.d("下发设置打开通知操作失败");
            }

            @Override
            public void onCharacteristicChanged(byte[] data) {
                for (Byte a : data) {
                    atShowResult.append(String.format("%02X", a));
                }
                mCountDownTimer.start();
                String sMes = HexUtil.hexStringToString(atShowResult.toString());
                if (sMes != null && sMes.trim().length() > 0) {
                    int iIndexOk = sMes.indexOf("OK");
                    int iIndexDeviceType = sMes.indexOf("DeviceType");
                    if (iIndexOk != -1 && iIndexDeviceType != -1) {
                        stopNotify();
                        isFinish = true;
                        mCountDownTimer.cancel();
//                        BleLog.d("BleUtils  == 返回数据 ===" + HexUtil.hexStringToString(atShowResult.toString()));
                        atShowCallBack.onResult(new StringBuffer(HexUtil.hexStringToString(atShowResult.toString())));
                    }
                }
            }

            @Override
            public void onError() {
                //关闭监听
                isFinish = true;
                BleLog.d("BleUtils ==onError== isFinish=== " + isFinish);
                atShowCallBack.onError("查询失败");
                stopNotify();
            }
        });
    }


    public static void sendAtSearchOrTakePicture(final boolean isPicture, final BleUtilCallBack atSearchCallBack) {
        isFinish = false;
        atSearchResult = new StringBuffer();
        atSearchResultByteList = new ArrayList<>();
        BleUtils.bleUtilCallBack = atSearchCallBack;
        BleUtils.notify(new BleNotifyCallback() {
            @Override
            public void onNotifySuccess() {
                String hexString = null;

                try {
                    if (isPicture) {
                        hexString = HexUtil.chineseWordToGbk("AT+BTTAKEPHOTOS=1") + "0D0A";
                    } else {
                        hexString = HexUtil.chineseWordToGbk("AT+SEARCH") + "0D0A";
                        mCountDownTimer.start();
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                BleUtils.write(BleUtils.getBleDevice(), hexString, new BleWriteCallback() {
                    @Override
                    public void onWriteSuccess(final int current, final int total, final byte[] justWrite) {
                        if (current == total) {
                            BleLog.d("下发设置发送成功");
//                            mCountDownTimer.start();
                        }
                    }

                    @Override
                    public void onWriteFailure(final BleException exception) {
                        atSearchCallBack.onWriteFailure("获取设备数失败");
                    }
                });

            }

            @Override
            public void onNotifyFailure(BleException exception) {
//                        BleLog.d("下发设置打开通知操作失败");
                atSearchCallBack.onError("查询失败");
            }

            @Override
            public void onCharacteristicChanged(byte[] data) {
                for (Byte a : data) {
                    atSearchResult.append(String.format("%02X", a));
                    atSearchResultByteList.add(a);
                }
                isFinish = true;
                String sMes = HexUtil.bytesToAscii(data);
                if (sMes != null && sMes.trim().length() > 0) {
                    int iIndexOk = sMes.indexOf("OK");
                    if (iIndexOk != -1) {
                        stopNotify();
                        mCountDownTimer.cancel();
                        if (isPicture) {
                            atSearchCallBack.onByte(Bytes.toArray(atSearchResultByteList));
                        } else {
                            atSearchCallBack.onResult(new StringBuffer(HexUtil.hexStringToString(atSearchResult.toString())));
                        }
                    }
                }
            }

            @Override
            public void onError() {
                //关闭监听
                isFinish = true;
                atSearchCallBack.onError("查询失败");
                stopNotify();
            }
        });
    }


    public interface BleUtilCallBack {
        void onWriteFailure(String message);

        void onSuccess(String message);

        void onError(String message);

        void onResult(StringBuffer message);

        void onByte(byte[] bytes);
    }

    public interface BleUtilLoginCallBack {
        void isLogin(boolean isSuccess,String message);
    }


    public static void removeCallbacksAndMessages(){
        submitHandler.removeCallbacksAndMessages(null);
    }

}
